namespace SimpleWebServices.Configuration
{
    using System;
    using System.Collections.ObjectModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;

    [XmlRoot("data")]
    public sealed class DataSettings : IXmlSerializable
    {
        public DataSettings()
        {
            this.XmlDataSettings = new Collection<XmlDataSetting>();
        }

        public bool? Enabled
        {
            get;
            set;
        }

        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Can't deserialize if the setter is private.")]
        public Collection<XmlDataSetting> XmlDataSettings
        {
            get;
            set;
        }

        public void Upsert()
        {
            if (this.Enabled.HasValue ? this.Enabled.Value : true)
            {
                foreach (XmlDataSetting setting in this.XmlDataSettings)
                {
                    setting.Upsert();
                }
            }
        }

        XmlSchema IXmlSerializable.GetSchema()
        {
            throw new NotSupportedException();
        }

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }

            string value = reader.GetAttribute("enabled");
            if (!string.IsNullOrEmpty(value))
            {
                this.Enabled = XmlConvert.ToBoolean(value);
            }

            if (reader.IsEmptyElement)
            {
                reader.Read();
            }
            else
            {
                string name = reader.Name;
                while (true)
                {
                    if (XmlNodeType.EndElement == reader.NodeType && reader.Name == name)
                    {
                        reader.Read();
                        break;
                    }
                    else if ("xml".Equals(reader.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        this.XmlDataSettings.Add(reader.ReadOuterXml().Deserialize<XmlDataSetting>());
                    }
                    else
                    {
                        reader.Read();
                    }
                }
            }
        }

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            if (null == writer)
            {
                throw new ArgumentNullException("writer");
            }

            if (this.Enabled.HasValue)
            {
                writer.WriteAttributeString("enabled", XmlConvert.ToString(this.Enabled.Value));
            }

            foreach (XmlDataSetting setting in this.XmlDataSettings)
            {
                writer.WriteRaw(setting.Serialize().CreateNavigator().OuterXml);
            }
        }
    }
}